<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .animateTest {
        position: absolute;
      }
      #firstDiv,
      .stopfather,
      .offsetFather,
      .clientTest {
        width: 300px;
        height: 300px;
        background-color: #ccc;
        margin-bottom: 20px;
      }
      .clientTest {
        border: 5px solid red;
      }
      .scrollTest {
        width: 100px;
        height: 100px;
        background-color: #ccc;
        margin-bottom: 20px;
        padding: 5px;
        overflow: auto;
      }
      .offsetFather {
        position: relative;
      }
      .fDiv,
      .stopson,
      .showOrHide,
      .offsetSon {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      .offsetSon {
        margin-left: 45px;
      }
      .testDiv {
        width: 300px;
        height: 300px;
        background-color: #ccc;
      }
      .testfather {
        width: 300px;
        height: 300px;
        background-color: blue;
      }
      .testson {
        width: 200px;
        height: 200px;
        background-color: red;
      }
    </style>
  </head>
  <body>
    <section>
      <button class="animateTest">我走了</button>
      <div class="scrollTest">
        scroll系列scroll系列scroll系列scroll系列scroll系列scroll系列scroll系列scroll系列scroll系列scroll系列scroll系列scroll系列
      </div>
      <div class="clientTest">client系列</div>
      <div class="offsetFather">
        <div class="offsetSon">offset系列</div>
      </div>
      <form action="Web index.html">
        请输入：<input type="text" name="uname" />
        <input type="submit" value="点我去看location的使用" />
      </form>
      <button class="locationBtn">点击我强制刷新页面</button>
      <button class="forwardPage">前进</button>
      <div class="showOrHide">改变窗口大小，我给你看魔术</div>
      <div id="firstDiv">
        <div class="fDiv">点我看e.target和this的区别</div>
      </div>
      <div class="stopfather">
        <div class="stopson">我会停止冒泡</div>
      </div>
      <a href="#">我不会跳转</a>
      <ul class="event-delegate">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
      </ul>
      <div class="testDiv">可以点我</div>
      <img src="../images/text.jpg" alt="" title="图片1" class="testImg" />
      <div class="testfather">
        <div class="testson">我会冒泡</div>
      </div>
      <ul>
        <li class="lis">1</li>
        <li>2</li>
        <li class="lis">3</li>
      </ul>
      <div class="grandparent">
        <div class="parent">
          <div class="son">儿子</div>
          <div class="daughter">女儿</div>
        </div>
        <div class="uncle"></div>
      </div>
      <!-- 本地存储 -->
      <div class="sessionTest">
        <input type="text" class="sessionInp" />
        <button class="setSession">存储数据</button>
        <button class="getSession">获取数据</button>
        <button class="removeSession">删除数据</button>
        <button class="clearSession">清空数据</button>
      </div>
      <div class="localTest">
        <input type="text" class="localInp" />
        <button class="setlocal">存储数据</button>
        <button class="getlocal">获取数据</button>
        <button class="removelocal">删除数据</button>
        <button class="clearlocal">清空数据</button>
      </div>
    </section>
    <script src="../js/js-basic.js"></script>
    <!-- Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM),可以查看MDN获取详情
          DOM是文档对象模型，可以通过该接口改变网页的内容、结构和样式,其对象名为 document
          BOM是浏览器对象模型，可以提供该接口与浏览器窗口进行交互,其对象名为 window -->
    <script>
      // DOM相关
      console.log("DOM相关");
      // 获取元素
      console.log("获取元素");
      // document.getElementById('id') 根据页面元素的id获取元素，返回元素对象
      var firstDiv = document.getElementById("firstDiv");
      console.log(firstDiv);
      console.log(typeof firstDiv);
      //console.dir() 打印返回的元素对象,方便查看其属性和方法
      console.dir(firstDiv);
      // document.getElementsByTagName('标签名') 根据页面元素的标签名获取元素
      // 返回获取来的元素对象的集合，以伪数组形式存储
      var lis = document.getElementsByTagName("li");
      console.log(lis);
      console.log(lis[1]);
      // document.getElementsByClassName('className') 根据页面元素的class获取元素
      var boxs = document.getElementsByClassName("box");
      console.log(boxs);
      // document.querySelector() 返回指定选择器的第一个元素对象
      //选择器需要加符号,如 类选择器：.box id选择器：#timer 标签选择器 li
      console.log(document.querySelector("ul"));
      console.log(document.querySelector(".lis"));
      console.log(document.querySelector("#firstDiv"));
      // document.querySelectorAll() 返回指定选择器的所有元素对象集合
      console.log(document.querySelectorAll("li"));
      // document.body 获取body元素
      console.log(document.body);
      // document.documentElement 获取html元素
      console.log(document.documentElement);

      console.log("---------------------------");
      //事件
      console.log("事件");
      /* 事件由事件源、事件类型、事件处理程序组成，称为事件三要素
          1.事件源是事件被触发的对象
          2.事件类型是怎么触发事件,事件类型有哪些去MDN看
          3.事件处理程序是触发后进行什么操作
          4.执行事件步骤：
              1)获取事件源
              2）绑定事件
              3）添加事件处理程序
          5.事件可以修改元素内容、样式、属性
      */
      // 1)获取事件源
      var div = document.querySelector(".testDiv");
      // 2）绑定事件 3)添加事件处理程序
      /* 绑定事件：
            1.传统方式：如onclick、onmouseover等
              传统方式同一个元素不能绑定多个同类型事件
            2.事件监听方式：element.addEventListener(type,listener[,useCapture])
              type：事件类型，如click、mouseover 要加引号，不要on
              listener：事件处理程序
              useCapture：一般省略 true处于捕获阶段，false或省略处于冒泡阶段
              事件监听方式同一个元素可以绑定多个同类型事件
            3.element.attachEvent(type,listener) ie9以前版本支持
         删除事件：
            1.传统方式：事件处理程序为null 如element.onclick=null
            2.事件监听方式：element.removeEventListener(type,listener)
            3.element.detachEvent(type,listener) */
      div.onclick = function () {
        /* 修改元素内容
            1.innerText 不识别html标签，去除空格和换行
            2.innerHTML 识别html标签，符合W3C标准，保留空格和换行 */
        this.innerHTML = "芜湖<ol><li>233</li></ol>";
        /* 修改元素样式
            元素名.style.属性名='属性值'
            1.属性名用驼峰命名法
            2.修改的属性是以行内样式添加的，优先级很高
            3.如果修改的样式较多，可以元素名.className为元素添加类名来修改样式 */
        this.style.backgroundColor = "pink";
        this.style.width = "200px";
        this.style.height = "200px";
      };
      // 修改元素属性 如src href value等
      var imgTest = document.querySelector(".testImg");
      imgTest.addEventListener("click", changeImg);
      function changeImg() {
        this.src = "../images/473973.png";
      }

      console.log("---------------------------");
      // 事件流
      console.log("事件流");
      /* 事件流：事件发生时在元素节点之间的传播过程
          1.捕获阶段：由DOM最顶层节点从上往下传播
          2.当前目标阶段
          3.冒泡阶段：由最具体的元素开始从下往上传播
         特点：
          1.js代码中只能执行捕获或冒泡中的一个
          2.onclick和attachEvent只能得到冒泡阶段
          3.部分事件没有冒泡，如onblur、onfocus、onmouseenter、onmouseleave*/
      // 捕获阶段 document->html->body->section->testfather->testson
      var testson = document.querySelector(".testson");
      var testfather = document.querySelector(".testfather");
      // testson.addEventListener(
      //   "click",
      //   function () {
      //     alert("son");
      //   },
      //   true
      // );
      // testfather.addEventListener(
      //   "click",
      //   function () {
      //     alert("father");
      //   },
      //   true
      // );
      //冒泡阶段 document<-html<-body<-section<-testfather<-testson
      testson.addEventListener("click", function () {
        alert("son");
      });
      testfather.addEventListener("click", function () {
        alert("father");
      });

      console.log("---------------------------");
      // 事件对象
      console.log("事件对象");
      /* 1.event就是一个事件对象，可作为形参写入函数的小括号里
         2.事件对象是系统在事件发生时创建的
         3.事件对象是事件的一系列相关数据的集合，如鼠标点击时的坐标
         4.事件对象可以自命名，如event、e
         5.ie678需要使用window.event */
      /* 事件对象的属性和方法
            1.e.target返回触发事件的对象
            2.this返回绑定事件的对象
              1）全局作用域或普通函数中this指向全局对象window
              2）方法调用中this指向调用该方法的对象
              3）构造函数中this指向构造函数的实例
            3.ie678不认识e.target,用e.srcElement
            4.currentTarget和this相似
         阻止默认事件,如链接不跳转，提交按钮不提交
            1.e.preventDefault();
            2.ie678使用e.returnValue
            3.return false;
            4.2和3方法只能用于传统注册事件
         阻止冒泡:
            1.e.stopPropagation()  (推荐)
            2.e.cancelBubble = true
         事件委托：
            给父节点添加事件，利用冒泡影响每一个子节点
          鼠标事件对象：MouseEvent
            1.e.clientX和e.clientY
              获取鼠标在可视区的x和y坐标
            2.e.pageX和e.pageY
              获取鼠标在页面文档的x和y坐标
            3.e.screenX和e.screenY
              获取鼠标在电脑屏幕的x和y坐标
            4.禁用右键菜单:阻止contextmenu默认事件
            5.禁用选中文字：阻止selectstart默认事件
          键盘事件对象：
            1.keyup 键盘按键松开触发
            2.keydown 键盘按键按下触发
            3.keypress 键盘按键按下触发 不识别功能键如ctrl、shift、箭头等
            4.三者执行顺序：keydown->keypress->keyup
            5.e.keyCode得到相应键的ASCII码值
                注：keypress区分大小写，keyup和keydown不区分大小写
            6.e.key得到相应按键值
          */
      //获取事件对象
      firstDiv.addEventListener("click", function (e) {
        e = e || window.event;
        console.log(e);
        var targetE = e.target || e.srcElement;
        console.log(targetE);
        console.log(this);
        console.log(e.currentTarget);
      });

      //阻止默认事件
      var a = document.querySelector("a");
      a.addEventListener("click", function (e) {
        e.preventDefault();
      });

      // 阻止冒泡
      var stopson = document.querySelector(".stopson");
      var stopfather = document.querySelector(".stopfather");
      stopson.addEventListener("click", function (e) {
        alert("son");
        e.stopPropagation();
        e.cancelBubble = true;
      });
      stopfather.addEventListener("click", function () {
        alert("father");
      });

      //事件委托
      var eventDelegate = document.querySelector(".event-delegate");
      eventDelegate.addEventListener("click", function (e) {
        e.target.style.backgroundColor = "red";
      });

      // 鼠标事件对象：MouseEvent
      eventDelegate.addEventListener("click", function (e) {
        console.log("鼠标在可视区的x坐标为：" + e.clientX);
        console.log("鼠标在可视区的y坐标为：" + e.clientY);
        console.log("鼠标在页面文档的x坐标为：" + e.pageX);
        console.log("鼠标在页面文档的y坐标为：" + e.pageY);
        console.log("鼠标在电脑屏幕的x坐标为：" + e.screenX);
        console.log("鼠标在电脑屏幕的y坐标为：" + e.screenY);
      });
      // 禁用右键菜单
      document.addEventListener("contextmenu", function (e) {
        e.preventDefault();
      });
      //禁用选中文字
      document.addEventListener("selectstart", function (e) {
        e.preventDefault();
      });
      //mouseenter和mouseover的区别
      /* 1.mouseover鼠标经过自身盒子触发，经过子盒子也触发；mouseenter只有鼠标经过自身盒子触发
         2.mouseover会冒泡，mouseenter不会冒泡
         3.mouseenter和mouseleave搭配使用
       */

      // 键盘事件对象
      document.addEventListener("keyup", function (e) {
        console.log("松开了" + e.key + "\t其ASCII码值为" + e.keyCode);
      });
      document.addEventListener("keydown", function (e) {
        console.log("按下了" + e.key + "\t其ASCII码值为" + e.keyCode);
      });
      document.addEventListener("keypress", function (e) {
        console.log("按下了" + e.key + "\t其ASCII码值为" + e.keyCode);
      });

      console.log("---------------------------");
      //元素属性
      console.log("元素属性");
      //获取元素属性
      /* 1.element.属性 一般用于获取系统属性
         2.element.getAttribute('属性') 一般用来获取自定义属性
         3.两者获取class时, 1的属性写className，2的属性直接写class*/
      console.log(imgTest.className);
      console.log(imgTest.getAttribute("class"));
      // 设置元素属性值
      /* 1.element.属性='值' 一般用于修改系统属性值
         2.element.setAttribute('属性','值') 一般用于修改自定义属性值
         3.两者修改class时，1的属性写className，2的属性直接写class*/
      firstDiv.className = "firstDiv1";
      console.log(firstDiv.className);
      firstDiv.setAttribute("class", "firstDiv2");
      firstDiv.setAttribute("data-index", "1");
      console.log(firstDiv.className);
      console.log(firstDiv.getAttribute("data-index"));
      // 移除属性
      // removeAttribute(属性)
      firstDiv.removeAttribute("data-index");
      console.log(firstDiv.getAttribute("data-index"));
      // 自定义属性
      /* 目的：
          保存并使用数据
         获取：
          1.element.getAttribute('属性')
          2.element.dataset.属性或element.dataset['属性']
            注:1.属性可以只写data-后面的
               2.如果自定义属性里有多个-连接的单词，获取时使用驼峰命名法
         设置:
          1.element.setAttribute('属性','值')
          2.标签内设置 属性='值'
         属性名规范（H5）:
          以data-开头，如data-index*/
      firstDiv.setAttribute("data-test-dataset", "233");
      console.log(firstDiv.dataset.testDataset);
      console.log(firstDiv.dataset["testDataset"]);

      console.log("---------------------------");
      // 节点操作
      console.log("节点操作");
      //父节点 节点.parentNode
      //得到距离当前节点最近的父级节点，如果找不到就返回null
      var son = document.querySelector(".son");
      console.log(son.parentNode);
      // 子节点
      /* 1.节点.childNodes
            返回当前节点的所有子节点，包括元素节点、文本节点（如换行）等
         2.节点.children(推荐)
            返回当前节点的所有子元素节点
         3.节点.firstChild
            返回当前节点的第一个子节点，包括元素节点、文本节点等
         4.节点.lastChild
            返回当前节点的最后一个子节点，包括元素节点、文本节点等
         5.节点.firstElementChild
            返回当前节点的第一个子元素节点
         6.节点.lastElementChild
            返回当前节点的最后一个子元素节点  */
      var grandparent = document.querySelector(".grandparent");
      console.log(grandparent.childNodes);
      console.log(grandparent.children);
      console.log(grandparent.firstChild);
      console.log(grandparent.firstElementChild);
      console.log(grandparent.children[0]);
      console.log(grandparent.lastChild);
      console.log(grandparent.lastElementChild);
      console.log(grandparent.children[grandparent.children.length - 1]);
      //判断节点类型 节点.nodeType
      //1表示元素节点，3表示文本节点等等
      console.log(grandparent.childNodes[0].nodeType);
      console.log(grandparent.childNodes[1].nodeType);

      //兄弟节点
      /* 1.节点.nextSibling
            返回下一个兄弟节点，包括元素节点、文本节点等
         2.节点.previousSibling
            返回上一个兄弟节点，包括元素节点、文本节点等
         3.节点.nextElementSibling
            返回下一个兄弟元素节点
         4.节点.previousElementSibling
            返回上一个兄弟元素节点*/
      console.log(son.nextSibling);
      console.log(son.previousSibling);
      console.log(son.nextElementSibling);
      console.log(son.previousElementSibling);

      //创建节点
      /* 1.document.createElement('') */
      var brother = document.createElement("div");

      //添加节点
      /* 1.节点.appendChild()
            节点添加子节点在后面
         2.节点.insertBefore(要插入的节点，被插入的节点)
         3.要插入的节点只能选择一个方法插入，同时使用1、2会按文档书写顺序显示 */
      grandparent.appendChild(brother);
      grandparent.insertBefore(brother, grandparent.children[0]);
      console.log(grandparent);

      //复制节点
      /* 节点.cloneNode */
      var cloneDiv = grandparent.children[0].cloneNode();
      grandparent.children[0].append(cloneDiv);

      //删除节点
      /* 节点.removeChild() */
      grandparent.removeChild(grandparent.children[2]);

      console.log("---------------------------");
      // 三种创建元素方式的区别
      console.log("三种创建元素方式的区别");
      /* 1.document.write()
            如果页面文档流加载完毕，再调用这句话会导致页面重绘
         2.element.innerHTML
            创建多个元素效率更高(不是拼接字符串，而是采用数组拼接)，结构复杂
         3.document.createElement
            创建多个元素效率比2低一些，但是结构清晰
      */

      console.log("---------------------------");
      //BOM相关
      //window的方法可以不加window
      console.log("BOM相关");
      console.log("---------------------------");
      //页面加载事件
      console.log("页面加载事件");
      /* 1.window.onload = function(){}或者window.addEventListener('load',function(){})
            1）当文档内容全部加载完毕触发
            2）该事件可以把js代码写道页面元素上方
            3）传统注册方式只能写一个该事件，如果有多个则以最后一个为准
            4）window.addEventListener没有3)的限制
         2.window.addEventListener("DOMContentLoaded", function () {});
            1)当DOM加载完毕触发，不包括样式表、图片、flash等
            2）ie9以上支持
            3）适用于页面图片很多的情况
            4)加载速度比load更快
         3.load触发：
            1）a标签的超链接
            2）F5刷新
            3）前进后退按钮
         4.pageshow 页面显示事件
            1)部分浏览器在后退时不会触发load事件，这时可以用pageshow事件
            2)pageshow事件在load事件触发后触发
            3)根据pageshow事件对象的persisted可以判断是否是缓存中的页面触发的pageshow事件
            4)pageshow事件要添加给window */
      window.onload = function () {
        console.log("页面加载完毕");
      };
      window.addEventListener("DOMContentLoaded", function () {
        console.log("DOM加载完毕");
      });

      console.log("---------------------------");
      //调整窗口大小事件
      console.log("调整窗口大小事件");
      /* 1.window.onresize = function(){}
         2.window.addEventListener('resize',function(){})
         3.window.innerWidth 得到当前窗口的宽度
         4.window.innerHeight 得到当前窗口的高度 */
      var showOrHide = document.querySelector(".showOrHide");
      onresize = function () {
        console.log(
          "窗口大小发生了变化，现在的窗口宽度为：" +
            innerWidth +
            "\t现在的窗口高度为：" +
            innerHeight
        );
        if (innerWidth <= 1000) {
          showOrHide.style.display = "none";
        } else {
          showOrHide.style.display = "block";
        }
      };

      console.log("---------------------------");
      //定时器
      console.log("定时器");
      /* 1.window.setTimeout(调用函数(回调函数)，延时时间)
            1)等待延时时间后调用函数
            2)延时时间的单位是毫秒，省略默认为0
            3)定时器最好有自己的标识符，方便多加定时器和停止定时器操作
            4)调用函数最好另写一个函数，可以多个定时器调用函数
         2.window.clearTimeout(定时器标识符) 停止由1方法设置的定时器
         3.window.setInterval(调用函数，间隔时间)
            1)每隔间隔时间后调用函数
            2)间隔时间的单位是毫秒，省略默认为0
            3)定时器最好有自己的标识符，方便多加定时器和停止定时器操作
            4)调用函数最好另写一个函数，可以多个定时器调用函数
         4.window.clearInterval(定时器标识符) 停止由3方法设置的定时器
       */
      function callback() {
        console.log("我是定时器");
      }
      var timer1 = setTimeout(callback, 3000);
      window.clearTimeout(timer1);
      var timer2 = setInterval(callback, 1000);
      window.clearInterval(timer2);

      // location对象
      /* 1.location.href  获取或设置URL
         2.location.search  返回参数
         3.location.host  返回主机（域名）
         4.location.port  返回端口号
         5.location.pathname  返回路径
         6.location.hash  返回片段
      */
      console.log(location);
      console.log(location.href);
      console.log(location.search);
      console.log(location.host);
      console.log(location.port);
      console.log(location.pathname);
      console.log(location.hash);

      //location方法
      /*
        1.location.assign() 跳转页面（重定向）
        2.location.replace() 替换当前页面
            因为不记录历史，所以不能后退页面
        3.location.reload() 重新加载页面
            相当于刷新页面；参数为true时强制刷新页面，会清理页面残余数据
       */
      var locationbtn = document.querySelector(".locationBtn");
      locationbtn.addEventListener("click", function () {
        // location.assign("index.html");
        // location.replace("index.html");
        location.reload(true);
      });

      // navigator对象
      /* 包含有关浏览器的消息
          1.navigator.userAgent 返回use-agent头部的值，用于判断用户设备*/
      //根据用户设备返回对应页面
      /*       if (
        navigator.userAgent.match(
          /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
        )
      ) {
        window.location.href = "index.html";
      } else {
        window.location.href = "Web APIs基础.html";
      } */
      console.log(navigator);

      //history对象
      /* 1.history.back() 后退
         2.history.forward() 前进
         3.history.go(参数) 正式前进，负数后退
      */
      var forwardPage = document.querySelector(".forwardPage");
      forwardPage.addEventListener("click", function () {
        // history.forward();
        history.go(1);
      });

      console.log("---------------------------");
      //元素偏移量 offset 系列
      console.log("元素偏移量 offset 系列");
      /* 1.element.offsetTop 
            返回元素相对带有定位父元素上方的偏移
         2.element.offsetLeft
            返回元素相对带有定位父元素左边框的偏移
         3.element.offsetWidth
            返回自身包括padding、border、内容的宽度，返回数值不带单位
         4.element.offsetHeight
            返回自身包括padding、border、内容的高度，返回数值不带单位
         5.element.offsetParent
            返回作为该元素带有定位的父元素，如果父元素都没有定位，则返回body    */
      var offsetFather = document.querySelector(".offsetFather");
      var offsetSon = document.querySelector(".offsetSon");
      //得到元素的偏移
      console.log(offsetFather.offsetTop);
      console.log(offsetFather.offsetLeft);
      console.log(offsetSon.offsetLeft);
      //得到元素的宽高
      console.log(offsetSon.offsetWidth);
      console.log(offsetSon.offsetHeight);
      //得到元素带有定位的父元素
      console.log(offsetFather.offsetParent);
      /* element.offsetParent和element.parentNode的区别：
          element.offsetParent返回最近一级带有定位的父元素
          element.parentNode返回最近一级的父元素，无所谓父元素有无定位 */
      console.log(offsetFather.parentNode);
      /* offset与style的区别：
            1.offset可以得到任意样式表中的样式，而style只能得到行内样式表中的样式
            2.offset得到的数值是没有单位的数字型，style是有单位的字符串型
            3.offsetWidth包含padding、border、width，style.width只有width
            4.offsetWidth是只读属性，不能赋值，style.width是可读写属性，可以赋值
       */

      console.log("---------------------------");
      //元素可视区 client 系列
      console.log("元素可视区 client 系列");
      /* 1.element.clientTop 返回元素上边框的大小
         2.element.clientLeft 返回元素左边框的大小
         3.element.clientWidth 返回自身包括padding、内容区的宽度，不包含border，返回数值不带单位
         4.element.clientHeight 返回自身包括padding、内容区的高度，不包含border，返回数值不带单位 */
      var clientTest = document.querySelector(".clientTest");
      console.log(clientTest.clientTop);
      console.log(clientTest.clientLeft);
      console.log(clientTest.clientWidth);
      console.log(clientTest.clientHeight);

      console.log("---------------------------");
      //元素滚动 scroll 系列
      console.log("元素滚动 scroll 系列");
      /* 1.element.scrollTop 返回当前内容区域距离滚动条上侧的距离，返回值不带单位
         2.element.scrollLeft 返回当前内容区域距离滚动条左侧的距离，返回值不带单位
         3.element.scrollWidth 返回自身实际(内容)的宽度,不包含边框，返回值不带单位
         4.element.scrollHeight 返回自身实际(内容)的高度,不包含边框，返回值不带单位*/
      var scrollTest = document.querySelector(".scrollTest");
      // 添加滚动事件scroll
      scrollTest.addEventListener("scroll", function () {
        console.log(scrollTest.scrollTop);
        console.log(scrollTest.scrollLeft);
      });
      console.log(scrollTest.scrollWidth);
      console.log(scrollTest.scrollHeight);

      console.log("---------------------------");
      // offset、client、scroll的区别
      console.log("offset、client、scroll的区别");
      /* 1.offset常用于获取元素位置 offsetTop offsetLeft
         2.client常用于获取元素大小 clientWidth clientHeight
         3.scroll常用于获取元素中内容滚动距离 scrollTop scrollLeft
            注：页面滚动距离以window.pageXoffset获得
         4.offset返回元素自身包括padding、border、内容的大小
           client返回元素包括padding、内容的大小
           scroll返回元素内容的大小
          */
      console.log("---------------------------");
      //动画
      console.log("动画");
      /* 使用：
          1.元素添加定位
          2.获取元素
          3.调用动画函数
      */
      var animateTest = document.querySelector(".animateTest");
      console.log(animateTest.offsetLeft);
      animateTest.addEventListener("click", function () {
        console.log(animateTest.innerHTML);
        if (animateTest.innerHTML == "我走了") {
          animateHorizontalMovement(animateTest, 1000, function () {
            animateTest.innerHTML = "我回来了";
          });
        } else {
          animateHorizontalMovement(animateTest, 8, function () {
            animateTest.innerHTML = "我走了";
          });
        }
      });

      console.log("---------------------------");
      //本地存储
      console.log("本地存储");
      /* 1.sessionStorage
            1)sessionStorage.setItem(key, value); 存储数据
            2)sessionStorage.getItem(key); 获取数据
            3)sessionStorage.removeItem(key); 删除数据
            4)sessionStorage.clear(); 清空数据
            5)生命周期为关闭浏览器窗口
            6)在同一个页面下数据可以共享
            7)以键值对形式存储使用
         2.localStorage
            1)localStorage.setItem(key, value); 存储数据
            2)localStorage.getItem(key); 获取数据
            3)localStorage.removeItem(key); 删除数据
            4)localStorage.clear(local
            5)生命周期为永久生效，除非手动删除
            6)可以在多个页面数据共享（同一个浏览器内）
            7)以键值对形式存储使用 */
      // 1.sessionStorage
      var sessionInp = document.querySelector(".sessionInp");
      var setSession = document.querySelector(".setSession");
      var getSession = document.querySelector(".getSession");
      var removeSession = document.querySelector(".removeSession");
      var clearSession = document.querySelector(".clearSession");
      setSession.addEventListener("click", function () {
        var val = sessionInp.value;
        sessionStorage.setItem("uname", val);
      });
      getSession.addEventListener("click", function () {
        console.log(sessionStorage.getItem("uname"));
      });
      removeSession.addEventListener("click", function () {
        sessionStorage.removeItem("uname");
      });
      clearSession.addEventListener("click", function () {
        sessionStorage.clear();
      });

      // 2.localStorage
      var localInp = document.querySelector(".localInp");
      var setlocal = document.querySelector(".setlocal");
      var getlocal = document.querySelector(".getlocal");
      var removelocal = document.querySelector(".removelocal");
      var clearlocal = document.querySelector(".clearlocal");
      setlocal.addEventListener("click", function () {
        var val = localInp.value;
        localStorage.setItem("uname", val);
      });
      getlocal.addEventListener("click", function () {
        console.log(localStorage.getItem("uname"));
      });
      removelocal.addEventListener("click", function () {
        localStorage.removeItem("uname");
      });
      clearlocal.addEventListener("click", function () {
        localStorage.clear();
      });
    </script>
  </body>
</html>
